﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace UFrame
{
    public enum UILayer
    {
        /// <summary>
        /// 背景层(比如主界面)
        /// </summary>
        Background = 0,

        /// <summary>
        /// 默认层(比如装备界面 物品界面)
        /// </summary>
        Default = 1,

        /// <summary>
        /// 弹出窗口层(比如提示框)
        /// </summary>
        Popup = 2,

        /// <summary>
        /// 跑马灯
        /// </summary>
        Top = 3,
    }

    public class UILayerData
    {
        public int sortingOrder = 0;
        public string rtName;
        public RectTransform rt;
    }

    public class UIDefineData
    {
        public string path;
        public string name;
        public int id;
    }

    /// <summary>
    /// UI管理器
    /// </summary>
    public static class UIMa
    {
        //private UIMa() { }

        private static GameObject mUIRoot;
        private static Dictionary<string, UIDefineData> mUIInfoDicStr = new Dictionary<string, UIDefineData>();
        private static Dictionary<int, UIDefineData> mUIInfoDic = new Dictionary<int, UIDefineData>();
        private static Dictionary<int, BaseUI> mUIDic = new Dictionary<int, BaseUI>();
        private static Dictionary<int, List<BaseUI>> mSubUIDic = new Dictionary<int, List<BaseUI>>();
        private static Dictionary<UILayer, UILayerData> mUILayerDic = new Dictionary<UILayer, UILayerData>();

        private static bool isInit = false;

        public static GameObject UIRoot
        {
            get { return mUIRoot; }

            set { mUIRoot = value; }
        }

        public static void Init(GameObject uiRoot)
        {
            if (isInit)
            {
                return;
            }

            mUIRoot = uiRoot;
            if (mUIRoot == null)
            {
                mUIRoot = new GameObject("UI");
                GameObject.DontDestroyOnLoad(mUIRoot);
            }
            isInit = true;

            mUILayerDic.Add(UILayer.Background, new UILayerData() { sortingOrder = 0, });
            mUILayerDic.Add(UILayer.Default, new UILayerData() { sortingOrder = 1000, });
            mUILayerDic.Add(UILayer.Popup, new UILayerData() { sortingOrder = 2000, });
            mUILayerDic.Add(UILayer.Top, new UILayerData() { sortingOrder = 3000, });

            Transform t = null;
            foreach (var layer in mUILayerDic)
            {
                string rtName = layer.Key.ToString();
                t = mUIRoot.transform.Find(rtName);
                RectTransform rt = null;
                if (t == null)
                {
                    GameObject go = new GameObject();
                    go.name = rtName;
                    t = go.transform;
                    t.SetParent(mUIRoot.transform);
                    t.position = Vector3.zero;
                    t.rotation = Quaternion.identity;
                    rt = go.AddComponent<RectTransform>();
                    rt.anchorMax = Vector2.one;
                    rt.anchorMin = Vector2.zero;
                    rt.offsetMax = Vector2.zero;
                    rt.offsetMin = Vector2.zero;
                }
                else
                {
                    rt = t as RectTransform;
                }

                layer.Value.rt = rt;
            }
        }

        public static void AddUIInfo(int id, string path)
        {
            if (path.EndsWith(".prefab") == false)
            {
                path = path + ".prefab";
            }

            UIDefineData uidata = new UIDefineData();
            int index = path.LastIndexOf(@"/");
            string s = path.Substring(index + 1);
            s = s.TrimEnd(".prefab".ToCharArray());

            uidata.name = s;
            uidata.id = id;
            uidata.path = path;
            mUIInfoDicStr.Add(uidata.name, uidata);
            mUIInfoDic.Add(id, uidata);

        }

        /// <summary>
        /// 使用EUI打开UI
        /// </summary>
        /// <param name="type"></param>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static BaseUI ShowUI(int type, object arg = null)
        {
            return ShowUI<BaseUI>(type, arg);
        }

        public static BaseUI ShowUI(string uiName, object arg = null)
        {
            int type = -1;
            if (mUIInfoDicStr.ContainsKey(uiName))
            {
                type = mUIInfoDicStr[uiName].id;
                return ShowUI(type, arg);
            }
            
            
            

            return null;
        }

        public static T ShowUI<T>(int type, object arg = null) where T : BaseUI
        {
            if (!mUIInfoDic.ContainsKey(type))
            {
                return null;
            }

            if (mUIDic.ContainsKey(type))
            {
                if (mUIDic[type].gameObject.activeInHierarchy == false)
                {
                    mUIDic[type].gameObject.SetActive(true);
                }
                mUIDic[type].OnRefreshUI(arg);
                //Debug.LogError("重复打开UI");
                return mUIDic[type] as T;
            }

            BaseUI ui = CreateUI(type, arg); //创建UI
            if (null == ui)
            {
                return null;
            }

            ui.uiType = type;
            if (!ui.OnInit(arg))
            {
                Debug.LogError("UI init failed : " + type + "  " + ui.GetType().Name);
                GameObject.Destroy(ui.gameObject);
                return null;
            }

            mUIDic.Add(type, ui);
            ui.OnRefreshUI(arg);

            GraphicRaycaster g = ui.GetComponent<GraphicRaycaster>();
            if (g == null)
            {
                g = ui.gameObject.AddComponent<GraphicRaycaster>();
            }

            Canvas c = ui.GetComponent<Canvas>();
            if (c == null)
            {
                c = ui.gameObject.AddComponent<Canvas>();
            }

            var uiData = mUILayerDic[ui.uiLayer];
            c.overrideSorting = true;
            c.sortingOrder = uiData.sortingOrder;
            c.transform.SetAsLastSibling();

            //Debug.Log("sortingOrder: " + c.sortingOrder);
            //Debug.Log("renderOrder: " + c.renderOrder);

            ui.transform.SetParent(uiData.rt, false);
            return ui as T;
        }

        private static BaseUI CreateUI(int type, object arg)
        {
            Object g = null;

            if (mUIInfoDic.ContainsKey(type))
            {
                g = ResourcesMa.Load<Object>(mUIInfoDic[type].path); //传递路径进去
            }

            if (null == g)
            {
                Debug.LogError(mUIInfoDic[type].path + " is not exit");
                return null;
            }

            GameObject go = GameObject.Instantiate(g) as GameObject;

            go.SetActive(true);
            BaseUI ui = go.GetComponent<BaseUI>();
            if (null == ui)
            {
                Debug.LogError("没有UI_Base " + mUIInfoDic[type].path);
                GameObject.Destroy(go);
                Resources.UnloadAsset(g);
                return null;
            }

            return ui;
        }

        public static void DestroyUI(int type)
        {
            if (mUIDic.ContainsKey(type))
            {
                mUIDic[type].OnDestroyUI();
                GameObject.Destroy(mUIDic[type].gameObject);
                mUIDic[type] = null;
            }
        }

        public static void DisplyUI(int type, bool isDisplay)
        {
            if (mUIDic.ContainsKey(type))
            {
                if (mUIDic[type].gameObject.activeInHierarchy != isDisplay)
                {
                    mUIDic[type].gameObject.SetActive(isDisplay);
                }
            }
        }

        public static T GetUIBase<T>(int type) where T : BaseUI
        {
            if (mUIDic.ContainsKey(type))
            {
                return mUIDic[type] as T;
            }

            return null;
        }

        public static bool IsShowUI(int type)
        {
            if (mUIDic.ContainsKey(type))
            {
                return mUIDic[type].gameObject.activeInHierarchy;
            }

            return false;
        }

        public static void RefreshUI(int type, object args)
        {
            if (mUIDic.ContainsKey(type))
            {
                mUIDic[type].OnRefreshUI(args);
            }
        }

        /// <summary>
        /// 子UI
        /// </summary>
        /// <param name="subId"></param>
        /// <param name="subUI"></param>
        public static void AddSubUI(int subId, BaseUI subUI)
        {
            if (mSubUIDic.ContainsKey(subId) == false)
            {
                mSubUIDic[subId] = new List<BaseUI>();
            }

            mSubUIDic[subId].Add(subUI);
        }
    }
}